import com.sun.media.ui.MessageBox;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Savepoint;
import java.util.Vector;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

/**
 * Represents the interface where the user can manage his keys
 */
public class GUIKeyManager extends javax.swing.JFrame {
    
    // Static reference to the interface
    public static GUIKeyManager frame;
    // Item listener for the key list
    private java.awt.event.ItemListener key_listener;
    // Item listener for the list of encryption types
    private java.awt.event.ItemListener encryption_type_listener;
    // Item listener for the list of encryption algorithms
    private java.awt.event.ItemListener encryption_listener;
    // Indicates if the item state of a combo box was triggered by manual input
    private boolean manual;
    
    /** Creates new form GUIKeyManager */
    public GUIKeyManager() {
        initComponents();
        this.manual = false;
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        GUIKeyManager.frame = this;
        
        this.txtPrivateKey.setEditable(false);
        this.txtPublicKey.setEditable(false);
        
        if(Settings.public_key_selected) {
            radioPublicKey.setSelected(true);
            radioPrivateKey.setSelected(false);
        } else {
            radioPublicKey.setSelected(false);
            radioPrivateKey.setSelected(true);
        }
        
        this.cmbEncryptionType.removeAllItems();
        this.cmbEncryptionType.addItem("Symmetric");
        this.cmbEncryptionType.addItem("Asymmetric");
        fillEncryptionsSymmetric();
        Key key = Settings.key;
        fillKeyList();
        Settings.key = key;
        
        // If there is no chosen key
        if(Settings.key != null) {
            bindUsedKey();
            radioPublicKey.setSelected(true);
            radioPrivateKey.setSelected(false);
        } else
            bindChosenKey();
        
        this.encryption_listener = new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmbEncryptionItemStateChanged(evt);
            }
        };
        
        this.encryption_type_listener = new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmbEncryptionTypeItemStateChanged(evt);
            }
        };
        
        this.key_listener = new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cmbKeysItemStateChanged(evt);
            }
        };
        
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
        cmbKeys.addItemListener(this.key_listener);
    }
    
    /**
     * Fills the cypher combo box with the available symmetric cyphers
     */
    public void fillEncryptionsSymmetric() {
        this.cmbEncryption.removeAllItems();
        this.cmbEncryption.addItem(new String("AES"));
        this.cmbEncryption.addItem(new String("Blowfish"));
        this.cmbEncryption.addItem(new String("DES"));
        this.cmbEncryption.addItem(new String("DESede"));
        this.cmbEncryption.addItem(new String("TripleDES"));
        this.cmbEncryption.addItem(new String("RC2"));
        this.cmbEncryption.addItem(new String("RC4"));
        this.cmbEncryption.addItem(new String("ARCFOUR"));
        this.cmbEncryption.addItem(new String("Rijndael"));
    }
    
    /**
     * Saves the key name when it is changed in the interface
     */
    private void saveKeyName() {
        int old_index = this.cmbKeys.getSelectedIndex();
        
        // Change the key name
        if(cmbEncryptionType.getSelectedIndex() == 0)
            Settings.changeKeyName(cmbKeys.getSelectedItem().toString(),txtKeyName.getText());
        else
            Settings.changeKeyName(cmbKeys.getSelectedItem().toString(),txtKeyName.getText());
        
        // Refill the key list and select the old key again
        fillKeyList();
        this.cmbKeys.setSelectedIndex(old_index);
    }
    
    /**
     * Fills the cypher combo box with the available asymmetric cyphers
     */
    public void fillEncryptionsAsymmetric() {
        this.cmbEncryption.removeAllItems();
        this.cmbEncryption.addItem(new String("RSA"));
    }
    
    /**
     * Change the interface to reflect the information of the information of the application's selected key
     */
    public void bindUsedKey() {
        // If there's a chosen key
        if(Settings.key != null) {
            // And this changed was automatically triggered (loading of form)
            if(!this.manual) {
                // And the key is symmetric
                if(Settings.key.type_key == Key.TypeOfKey.Symmetric) {
                    // Fill encryption list with symmetric cyphers
                    cmbEncryptionType.setSelectedIndex(0);
                    fillEncryptionsSymmetric();
                } else {
                    // Fill encryption list with asymmetric cyphers
                    cmbEncryptionType.setSelectedIndex(1);
                    fillEncryptionsAsymmetric();
                }
                // Change the encryption list combo box to show the selected encryption
                cmbEncryption.setSelectedItem(Key.typeEncryption2String(Settings.key.type_encryption));
            }
            
            // Fill key list and select appropriate key
            fillKeyList();
            
            for(int x = 0; x < cmbKeys.getItemCount(); x++)
                if(cmbKeys.getItemAt(x).toString().equals(Settings.key.name))
                    cmbKeys.setSelectedIndex(x);
            
            // Change the form to reflect the key's informations
            this.txtKeyName.setText(Settings.key.name);
            this.txtPublicKey.setText(Settings.key.getPublicKey());
            this.txtPrivateKey.setText(Settings.key.getPrivateKey());
            GUI.frame.enableInterface(true);
        }
    }
    
    /**
     * Change the interface to reflect the manually chosen key
     */
    public void bindChosenKey() {
        // If the key list has at least a key (no null clicks)
        if(cmbKeys.getItemCount() > 0) {
            // If the chosen key is for a symmetric cypher
            if(cmbEncryptionType.getSelectedItem().toString().equals("Symmetric")) {
                Settings.key = Settings.symmetric_keys.get(Settings.getIndexByName(Settings.symmetric_keys,cmbKeys.getSelectedItem().toString()));
                bindUsedKey();
            } else { // If the chosen key is for an assymetric cypher
                Settings.key = Settings.assymetric_keys.get(Settings.getIndexByName(Settings.assymetric_keys,cmbKeys.getSelectedItem().toString()));
                bindUsedKey();
            }
        } else {
            txtKeyName.setText("");
            txtPublicKey.setText("");
            txtPrivateKey.setText("");
        }
    }
    
    /**
     * Updates the list of keys in the interface
     */
    public void fillKeyList() {
        // Clear the list
        this.cmbKeys.removeAllItems();
        
        // Fill the list with the appropriate keys
        Key.TypeOfEncryption encryption_type = Key.string2TypeEncryption(cmbEncryption.getSelectedItem().toString());
        if(cmbEncryptionType.getSelectedItem().toString().equals("Symmetric")){
            for(int x = 0; x < Settings.symmetric_keys.size(); x++)
                if(Settings.symmetric_keys.get(x).type_encryption == encryption_type)
                    this.cmbKeys.addItem(Settings.symmetric_keys.get(x).name);
        } else {
            for(int y = 0; y < Settings.assymetric_keys.size(); y++)
                if(Settings.assymetric_keys.get(y).type_encryption == encryption_type)
                    this.cmbKeys.addItem(Settings.assymetric_keys.get(y).name);
        }
        
        enableDisableInterface();
    }
    
    /**
     * Enable or disable the interface accordingly
     */
    private void enableDisableInterface() {
        // If the list is empty, then disable interface, or else, enable it
        boolean flag = true;
        if(cmbKeys.getItemCount() == 0) {
            flag = false;
            GUI.frame.enableInterface(false);
            Settings.key = null;
        }
        btnDeleteKey.setEnabled(flag);
        btnExportKey.setEnabled(flag);
        cmbKeys.setEnabled(flag);
        txtKeyName.setEnabled(flag);
        
        if(Settings.key != null && Settings.key.type_key == Key.TypeOfKey.Symmetric) {
            txtPrivateKey.setEnabled(false);
            radioPrivateKey.setEnabled(false);
            radioPublicKey.setEnabled(true);
            txtPublicKey.setEnabled(true);
            btnImportCertificate.setEnabled(false);
            btnExportPublic.setEnabled(false);
            btnExportPrivate.setEnabled(false);
            btnExportCertificate.setEnabled(false);
            radioPublicKey.setSelected(true);
            radioPrivateKey.setSelected(false);
        } else
            if(Settings.key != null && Settings.key.type_key == Key.TypeOfKey.Asymmetric) {
            txtPrivateKey.setEnabled(true);
            radioPrivateKey.setEnabled(true);
            radioPublicKey.setEnabled(true);
            txtPublicKey.setEnabled(true);
            btnImportCertificate.setEnabled(true);
            btnExportPublic.setEnabled(true);
            btnExportCertificate.setEnabled(true);
            btnExportPrivate.setEnabled(true);
            } else {
            txtPrivateKey.setEnabled(flag);
            radioPrivateKey.setEnabled(flag);
            radioPublicKey.setEnabled(flag);
            txtPublicKey.setEnabled(flag);
            btnExportPublic.setEnabled(flag);
            btnImportCertificate.setEnabled(flag);
            btnExportCertificate.setEnabled(flag);
            btnExportPrivate.setEnabled(flag);
            }
    }
    
    /**
     * Changes the interface according to the chosen encryption
     */
    private void encryptionChanged() {
        fillKeyList();
        bindChosenKey();
    }
    
    /**
     * Changes the interface according to the chosen encryption type
     */
    private void encryptionTypeChanged() {
        if(cmbEncryptionType.getSelectedItem().toString().equals("Symmetric"))
            fillEncryptionsSymmetric();
        else
            fillEncryptionsAsymmetric();
        encryptionChanged();
    }
    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        jScrollPane2 = new javax.swing.JScrollPane();
        jList2 = new javax.swing.JList();
        btnOk = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabelType = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        txtPublicKey = new javax.swing.JTextArea();
        jScrollPane4 = new javax.swing.JScrollPane();
        txtPrivateKey = new javax.swing.JTextArea();
        cmbEncryption = new javax.swing.JComboBox();
        txtKeyName = new javax.swing.JTextField();
        jLabelType1 = new javax.swing.JLabel();
        cmbKeys = new javax.swing.JComboBox();
        btnGenerateKey = new javax.swing.JButton();
        btnDeleteKey = new javax.swing.JButton();
        jLabelType2 = new javax.swing.JLabel();
        cmbEncryptionType = new javax.swing.JComboBox();
        btnImportKey = new javax.swing.JButton();
        btnExportKey = new javax.swing.JButton();
        btnExportPublic = new javax.swing.JButton();
        btnExportPrivate = new javax.swing.JButton();
        radioPublicKey = new javax.swing.JRadioButton();
        radioPrivateKey = new javax.swing.JRadioButton();
        btnExportCertificate = new javax.swing.JButton();
        btnImportCertificate = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Locksmith - Key Manager");
        jList2.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane2.setViewportView(jList2);

        btnOk.setText("Apply");
        btnOk.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnOkMousePressed(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel1.setText("Key Management");

        jLabelType.setText("Encryption:");

        txtPublicKey.setColumns(20);
        txtPublicKey.setLineWrap(true);
        txtPublicKey.setRows(5);
        txtPublicKey.setEnabled(false);
        jScrollPane3.setViewportView(txtPublicKey);

        txtPrivateKey.setColumns(20);
        txtPrivateKey.setLineWrap(true);
        txtPrivateKey.setRows(5);
        txtPrivateKey.setEnabled(false);
        jScrollPane4.setViewportView(txtPrivateKey);

        cmbEncryption.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        txtKeyName.setEnabled(false);
        txtKeyName.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtKeyNameFocusLost(evt);
            }
        });
        txtKeyName.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtKeyNameKeyPressed(evt);
            }
        });

        jLabelType1.setText("Name:");

        cmbKeys.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        cmbKeys.setEnabled(false);

        btnGenerateKey.setText("Generate");
        btnGenerateKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnGenerateKeyMousePressed(evt);
            }
        });

        btnDeleteKey.setText("Delete");
        btnDeleteKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnDeleteKeyMousePressed(evt);
            }
        });

        jLabelType2.setText("Type:");

        cmbEncryptionType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        btnImportKey.setText("Import");
        btnImportKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnImportKeyMousePressed(evt);
            }
        });

        btnExportKey.setText("Export");
        btnExportKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnExportKeyMousePressed(evt);
            }
        });

        btnExportPublic.setText("Export");
        btnExportPublic.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnExportPublicMousePressed(evt);
            }
        });

        btnExportPrivate.setText("Export");
        btnExportPrivate.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnExportPrivateMousePressed(evt);
            }
        });

        radioPublicKey.setText("Public Key:");
        radioPublicKey.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        radioPublicKey.setMargin(new java.awt.Insets(0, 0, 0, 0));
        radioPublicKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                radioPublicKeyMousePressed(evt);
            }
        });

        radioPrivateKey.setText("Private Key:");
        radioPrivateKey.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        radioPrivateKey.setMargin(new java.awt.Insets(0, 0, 0, 0));
        radioPrivateKey.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                radioPrivateKeyMousePressed(evt);
            }
        });

        btnExportCertificate.setText("Export Certificate");
        btnExportCertificate.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnExportCertificateMousePressed(evt);
            }
        });

        btnImportCertificate.setText("Import Certificate");
        btnImportCertificate.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnImportCertificateMousePressed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jLabel1)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(jPanel1Layout.createSequentialGroup()
                                .add(radioPrivateKey)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 269, Short.MAX_VALUE)
                                .add(btnExportPrivate))
                            .add(jPanel1Layout.createSequentialGroup()
                                .add(radioPublicKey)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 27, Short.MAX_VALUE)
                                .add(btnImportCertificate)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(btnExportCertificate)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(btnExportPublic))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1Layout.createSequentialGroup()
                                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(jLabelType1)
                                    .add(jLabelType2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 41, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(jPanel1Layout.createSequentialGroup()
                                        .add(cmbEncryptionType, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 126, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 48, Short.MAX_VALUE)
                                        .add(jLabelType)
                                        .add(14, 14, 14)
                                        .add(cmbEncryption, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 125, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                    .add(txtKeyName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, cmbKeys, 0, 413, Short.MAX_VALUE)
                            .add(jPanel1Layout.createSequentialGroup()
                                .add(btnGenerateKey, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(btnDeleteKey, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 101, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(btnImportKey, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 96, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(btnExportKey, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 93, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                        .add(13, 13, 13)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jLabel1)
                .add(15, 15, 15)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btnExportKey)
                    .add(btnDeleteKey, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 23, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(btnImportKey)
                    .add(btnGenerateKey))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(cmbKeys, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 22, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabelType1)
                    .add(txtKeyName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 20, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(cmbEncryption, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabelType2)
                    .add(cmbEncryptionType, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabelType))
                .add(14, 14, 14)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btnExportPublic, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(radioPublicKey)
                    .add(btnExportCertificate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(btnImportCertificate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 54, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btnExportPrivate, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 19, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(radioPrivateKey))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 57, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(54, 54, 54))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 125, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                        .add(btnOk, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 82, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 0, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 345, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(btnOk)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    private void btnImportCertificateMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnImportCertificateMousePressed
        // Remove interface listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        // If the import key button is indeed enabled
        if(btnImportKey.isEnabled()) {
            // Configure file request
            JFileChooser fc = new JFileChooser();
            String path_source = new String("");
            String path_destination = new String("");
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            fc.setFileFilter(new FilterCertificate());
            
            // Request source file
            if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                path_source = fc.getSelectedFile().getAbsolutePath();
                try {
                    new Encrypter().decryptFile(path_source,"temp");
                    // Load object from file and add to application key chain
                    FileInputStream f_in = new FileInputStream("temp");
                    ObjectInputStream obj_in = new ObjectInputStream(f_in);
                    Boolean certificate = (Boolean) obj_in.readObject();
                    String name = "";
                    String company = "";
                    if(certificate) {
                        name = (String) obj_in.readObject();
                        company = (String) obj_in.readObject();
                    }
                    Key key = (Key) obj_in.readObject();
                    JOptionPane.showMessageDialog(GUI.frame, "The imported public key, named \""+key.name+"\" is signed by \"" + name + " - " + company + "\"","Digital Certificate",JOptionPane.WARNING_MESSAGE);
                    Settings.addKey(key);
                    f_in.close();
                    new File("temp").delete();
                    fillKeyList();
                    bindChosenKey();
                } catch (FileNotFoundException ex) {
                    ex.printStackTrace();
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch (ClassNotFoundException ex) {
                    ex.printStackTrace();
                }
            }
        }
        
        // Insert interface listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }//GEN-LAST:event_btnImportCertificateMousePressed
    
    /**
     * Event invoked when the export certificate button is pressed
     */
    private void btnExportCertificateMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExportCertificateMousePressed
        new GUICertificateGenerator().setVisible(true);
        this.setVisible(false);
    }//GEN-LAST:event_btnExportCertificateMousePressed
    
    /**
     * Event invoked when a key is pressed in the key name textbox
     */
    private void txtKeyNameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtKeyNameKeyPressed
        if(evt.getKeyChar() == '\n')
            saveKeyName();
    }//GEN-LAST:event_txtKeyNameKeyPressed
    
    /**
     * Event invoked when the focus for the key name is lost
     */
    private void txtKeyNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtKeyNameFocusLost
        saveKeyName();
    }//GEN-LAST:event_txtKeyNameFocusLost
    
    /**
     * Event invoked when an encryption scheme is chosen
     */
    private void cmbEncryptionItemStateChanged(java.awt.event.ItemEvent evt) {
        // Remove listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        this.manual = true;
        fillKeyList();
        bindChosenKey();
        this.manual = false;
        
        // Adds listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }
    
    /**
     * Event invoked when a key is chosen
     */
    private void cmbKeysItemStateChanged(java.awt.event.ItemEvent evt) {
        // Remove listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        bindChosenKey();
        
        // Add listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }
    
    /**
     * Event invoked when the type of encryption is chosen
     */
    private void cmbEncryptionTypeItemStateChanged(java.awt.event.ItemEvent evt) {
        // Remove listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        
        encryptionTypeChanged();
        
        // Add listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }
    
    /**
     * Event invoked when the public key is selected
     */
    private void radioPublicKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_radioPublicKeyMousePressed
        if(radioPublicKey.isEnabled()) {
            radioPrivateKey.setSelected(false);
            Settings.public_key_selected = true;
        }
    }//GEN-LAST:event_radioPublicKeyMousePressed
    
    /**
     * Event invoked when the private key is selected
     */
    private void radioPrivateKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_radioPrivateKeyMousePressed
        if(radioPrivateKey.isEnabled()) {
            radioPublicKey.setSelected(false);
            Settings.public_key_selected = false;
        }
    }//GEN-LAST:event_radioPrivateKeyMousePressed
    
    /**
     * Exports a key to a file
     * @param is_public Boolean indicating if the public part of the key should be exported
     * @param is_private Boolean indicating if the private part of the key should be exported
     */
    private void exportKey(boolean is_public, boolean is_private) {
        if((!is_public && is_private) || (is_public && !is_private) || (is_public && is_private)) {
            
            // Configure file requester
            JFileChooser fc = new JFileChooser();
            String path_source = new String("");
            String path_destination = new String("");
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            
            if(is_public && !is_private)
                fc.setFileFilter(new FilterPublic());
            else
                if(!is_public && is_private)
                    fc.setFileFilter(new FilterPrivate());
                else
                    if(is_public && is_private)
                        fc.setFileFilter(new FilterKey());
            
            
            // Request destination file
            if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                path_destination = file.getAbsolutePath();
                String ext = Utilities.getExtension(file);
                if(ext == null)
                    ext = "";
                
                if(is_public && !is_private && !ext.equals("pub"))
                    path_destination += ".pub";
                else
                    if(!is_public && is_private && !ext.equals("prv"))
                        path_destination += ".prv";
                    else
                        if(is_public && is_private && !ext.equals("key"))
                            path_destination += ".key";
                
                // Save the key to the destination file
                try {
                    FileOutputStream f_out = new FileOutputStream(path_destination);
                    ObjectOutputStream obj_out = new ObjectOutputStream(f_out);
                    
                    // Clear out the undesired parts of the key
                    Key out = (Key) Utilities.clone(Settings.key);
                    if(!is_public)
                        out.public_key = null;
                    if(!is_private)
                        out.private_key = null;
                    
                    obj_out.writeObject(out);
                    f_out.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    
    /**
     * Event invoked when the export private key button is pressed
     */
    private void btnExportPrivateMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExportPrivateMousePressed
        if(btnExportPrivate.isEnabled())
            exportKey(false,true);
    }//GEN-LAST:event_btnExportPrivateMousePressed
    
    /**
     * Event invoked when the export public key button is pressed
     */
    private void btnExportPublicMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExportPublicMousePressed
        if(btnExportPublic.isEnabled())
            exportKey(true,false);
    }//GEN-LAST:event_btnExportPublicMousePressed
    
    /**
     * Event invoked when the export key button is pressed
     */
    private void btnExportKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnExportKeyMousePressed
        if(btnExportKey.isEnabled())
            exportKey(true,true);
    }//GEN-LAST:event_btnExportKeyMousePressed
    
    /**
     * Event invoked when the import key button is pressed
     */
    private void btnImportKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnImportKeyMousePressed
        // Remove interface listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        // If the import key button is indeed enabled
        if(btnImportKey.isEnabled()) {
            // Configure file request
            JFileChooser fc = new JFileChooser();
            String path_source = new String("");
            String path_destination = new String("");
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            fc.setFileFilter(new FilterAnyKey());
            
            // Request source file
            if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                path_source = fc.getSelectedFile().getAbsolutePath();
                try {
                    // Load object from file and add to application key chain
                    FileInputStream f_in = new FileInputStream(path_source);
                    ObjectInputStream obj_in = new ObjectInputStream(f_in);
                    Key key = (Key) obj_in.readObject();
                    Settings.addKey(key);
                    f_in.close();
                    fillKeyList();
                    bindChosenKey();
                } catch (FileNotFoundException ex) {
                    ex.printStackTrace();
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch (ClassNotFoundException ex) {
                    ex.printStackTrace();
                }
            }
        }
        
        // Insert interface listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }//GEN-LAST:event_btnImportKeyMousePressed
    
    /**
     * Event invoked when the delete key button is pressed
     */
    private void btnDeleteKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnDeleteKeyMousePressed
        // Remove interface listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        // If the delete key button is indeed enabled
        if(btnDeleteKey.isEnabled()) {
            if(cmbEncryptionType.getSelectedIndex() == 0)
                Settings.symmetric_keys.remove(Settings.getIndexByName(Settings.symmetric_keys,cmbKeys.getSelectedItem().toString()));
            else
                Settings.assymetric_keys.remove(Settings.getIndexByName(Settings.assymetric_keys,cmbKeys.getSelectedItem().toString()));
            
            fillKeyList();
            bindChosenKey();
        }
        
        // Insert interface listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }//GEN-LAST:event_btnDeleteKeyMousePressed
    
    /**
     * Event invoked when the generate key button is pressed
     */
    private void btnGenerateKeyMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnGenerateKeyMousePressed
        // Remove interface listeners
        cmbKeys.removeItemListener(this.key_listener);
        cmbEncryption.removeItemListener(this.encryption_listener);
        cmbEncryptionType.removeItemListener(this.encryption_type_listener);
        
        if(cmbEncryptionType.getSelectedIndex() == 0)
            Settings.symmetric_keys.add(new Key(Utilities.generateRandomString(10),Key.TypeOfKey.Symmetric,Key.string2TypeEncryption(cmbEncryption.getSelectedItem().toString())));
        else
            Settings.assymetric_keys.add(new Key(Utilities.generateRandomString(10),Key.TypeOfKey.Asymmetric,Key.string2TypeEncryption(cmbEncryption.getSelectedItem().toString())));
        fillKeyList();
        if(cmbKeys.getItemCount() > 0)
            cmbKeys.setSelectedIndex(cmbKeys.getItemCount() - 1);
        bindChosenKey();
        
        // Insert interface listeners
        cmbKeys.addItemListener(this.key_listener);
        cmbEncryption.addItemListener(this.encryption_listener);
        cmbEncryptionType.addItemListener(this.encryption_type_listener);
    }//GEN-LAST:event_btnGenerateKeyMousePressed
    
    /**
     * Event invoked when the OK button is pressed
     */
    private void btnOkMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnOkMousePressed
        Key key = null;
        if(cmbKeys.getItemCount() > 0) {
            if(cmbEncryptionType.getSelectedItem().equals("Symmetric"))
                key = Settings.symmetric_keys.get(Settings.getIndexByName(Settings.symmetric_keys,cmbKeys.getSelectedItem().toString()));
            else
                key = Settings.assymetric_keys.get(Settings.getIndexByName(Settings.assymetric_keys,cmbKeys.getSelectedItem().toString()));
            
            Settings.key = key;
        }
        GUI.frame.setVisible(true);
        this.dispose();
    }//GEN-LAST:event_btnOkMousePressed
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnDeleteKey;
    private javax.swing.JButton btnExportCertificate;
    private javax.swing.JButton btnExportKey;
    private javax.swing.JButton btnExportPrivate;
    private javax.swing.JButton btnExportPublic;
    private javax.swing.JButton btnGenerateKey;
    private javax.swing.JButton btnImportCertificate;
    private javax.swing.JButton btnImportKey;
    private javax.swing.JButton btnOk;
    private javax.swing.JComboBox cmbEncryption;
    private javax.swing.JComboBox cmbEncryptionType;
    private javax.swing.JComboBox cmbKeys;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabelType;
    private javax.swing.JLabel jLabelType1;
    private javax.swing.JLabel jLabelType2;
    private javax.swing.JList jList2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JRadioButton radioPrivateKey;
    private javax.swing.JRadioButton radioPublicKey;
    private javax.swing.JTextField txtKeyName;
    private javax.swing.JTextArea txtPrivateKey;
    private javax.swing.JTextArea txtPublicKey;
    // End of variables declaration//GEN-END:variables
    
}